﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows.Input;
using StressTesterCommon;
using StressServer;


namespace StressServer.ViewModel
{
    public class ClientProxyViewModel:INotifyPropertyChanged
    {
        #region NotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
        #region Event declarations
        public delegate void TestCompleted(ClientProxyViewModel Client);
        public event TestCompleted OnTestCompleted;
        public delegate void QueryResultRecieved(ClientProxyViewModel Client, QueryResult Result);
        public event QueryResultRecieved OnQueryResultRecieved;
        public delegate void Disconnect(ClientProxyViewModel Client);
        public event Disconnect OnDisconnect;
        public delegate void TestConnectionRecieved(ClientProxyViewModel Client, bool Success);
        public event TestConnectionRecieved OnTestConnectionRecieved;
        public delegate void ConfiguredRecieved(ClientProxyViewModel Client, bool Success);
        public event ConfiguredRecieved OnConfiguredRecieved;
        public delegate void TestAborted(ClientProxyViewModel Client);
        public event TestAborted OnTestAborted;
        #endregion
        #region Command declarations
        private ICommand _CommandDisconnectClient;
        public ICommand CommandDisconnectClient
        {
            get { return _CommandDisconnectClient; }
        }
       
        #endregion
        #region Constructors
        public ClientProxyViewModel(StressClientProxy Proxy)
        {
            _Client = Proxy;
            Status = "Connected and waiting";
            _CommandDisconnectClient = new RelayCommand(ExecuteDisconnectClient) { IsEnabled = true };
            _Client.QueryResultRecieved += _Client_QueryResultRecieved;
            _Client.OnTestconfigurationOk += _Client_OnTestconfigurationOk;
            _Client.OnTestconfigurationFailed += _Client_OnTestconfigurationFailed;
            _Client.OnTestConnectionFailed += _Client_OnTestConnectionFailed;
            _Client.OnTestConnectionOk += _Client_OnTestConnectionOk;
            _Client.OnClientTestStarted += _Client_OnClientTestStarted;
            _Client.OnDisconnect += _Client_OnDisconnect;
            _Client.OnTestAborted += _Client_OnTestAborted;
            _Client.OnClientTestCompleted+=_Client_OnClientTestCompleted;
            _ErrorCount = 0;
            
        }

        void _Client_QueryResultRecieved(StressClientProxy Client, QueryResult Result)
        {
            if (OnQueryResultRecieved != null)
            {
                OnQueryResultRecieved(this, Result);
            }
        }


        #endregion
        #region Members

        private int _QueryErrors;

        public int QueryErrors
        {
            get { return _QueryErrors; }
            set { _QueryErrors = value; OnPropertyChanged("QueryErrors"); }
        }
        private int _ClientsAbortedTestCount = 0;

        public int ClientsAbortedTestCount
        {
            get { return _ClientsAbortedTestCount; }
            set { _ClientsAbortedTestCount = value; }
        }
        
        private string _Status = "Connected and waiting";
        public string Status
        {
            get { return _Status; }
            set { if (_Status != value) { _Status = value; OnPropertyChanged("Status"); } }
        }
        private StressClientProxy _Client;
        private int _TotalQueryCount;
        public int TotalQueryCount
        {
            get { return _TotalQueryCount; }
            set { if (value != _TotalQueryCount) { _TotalQueryCount = value; OnPropertyChanged("TotalQueryCount"); } }
        }

        private int _TestCompletedStatus = 0;
        public int TestCompletedStatus
        {
            get { return _TestCompletedStatus; }
            set { _TestCompletedStatus = value; OnPropertyChanged("TestCompletedStatus"); }
        }


        private int _StartedStatus = 0;
        public int StartedStatus
        {
            get { return _StartedStatus; }
            set { _StartedStatus = value; OnPropertyChanged("StartedStatus"); }
        }
        private int _ConfigureStatus = 0;
        public int ConfigureStatus
        {
            get { return _ConfigureStatus; }
            set { if (_ConfigureStatus != value) { _ConfigureStatus = value; OnPropertyChanged("ConfigureStatus"); } }
        }
        private int _TestConnectionStatus;
        public int TestConnectionStatus
        {
            get { return _TestConnectionStatus; }
            set { if (value != _TestConnectionStatus) { _TestConnectionStatus = value; OnPropertyChanged("TestConnectionStatus"); } }
        }
        private int _ErrorCount = 0;
        public int ErrorCount
        {
            get { return _ErrorCount; }
            set { _ErrorCount = value; OnPropertyChanged("ErrorCount"); }
        }
        private int _QueriesCompleted;
        public int QueriesCompleted
        {
            get { return _QueriesCompleted; }
            set { _QueriesCompleted = value; OnPropertyChanged("QueriesCompleted"); }
        }
        public Guid Id
        {
            get { return _Client.Id; }
        }
        public string UserAndDomainName
        {
            get
            {
                return _Client.DomainName + "/" + _Client.UserName;
            }
        }
        public string IP
        {
            get { return _Client.IP; }
        }
        public string MachineName
        {
            get { return _Client.MachineName; }
        }
        public string DomainName
        {
            get { return _Client.DomainName; }
        }
        public string UserName
        {
            get { return _Client.UserName; }
        }
        #endregion
        #region Command implementations
        private void ExecuteDisconnectClient()
        {
            Status = "Disconnecting";
            _Client.Disconnect();
        }
        #endregion
        #region Events
        void _Client_OnTestConnectionOk()
        {
            this.TestConnectionStatus = 1;
            if (OnTestConnectionRecieved != null)
            {
                OnTestConnectionRecieved(this,true);
            }
        }

        void _Client_OnTestConnectionFailed()
        {
            this.ErrorCount++;
            this.TestConnectionStatus = 2;
            Status = "Could not connect to target";
            if (OnTestConnectionRecieved != null)
            {
                OnTestConnectionRecieved(this,false);
            }
        }

        void _Client_QueryResultRecieved(Guid Id, StressTesterCommon.QueryResult Result)
        {
            QueriesCompleted++;
            if (Result.ExecuteStatus == QueryExecuteStatus.QueryFailed)
            {
                QueryErrors++;
            }

            if (OnQueryResultRecieved != null)
            {
                OnQueryResultRecieved(this,Result);
            }
        }
        void _Client_OnTestconfigurationFailed()
        {
            this.ErrorCount++;
            this.ConfigureStatus = 2;
            Status = "Test configuration failed";
            if (OnConfiguredRecieved != null)
            {
                OnConfiguredRecieved(this,false);
            }
        }
        void _Client_OnTestAborted()
        {
            Status = "Test aborted";
            if (OnTestAborted != null)
            {
                OnTestAborted(this);
            }
        }
        void _Client_OnTestconfigurationOk()
        {

            this.ConfigureStatus = 1;
            if (OnConfiguredRecieved != null)
            {
                OnConfiguredRecieved(this, true);
            }
        }

        void _Client_OnClientTestCompleted(Guid Id)
        {
            TestCompletedStatus = 1;
            Status = "Test completed";
            if (OnTestCompleted != null)
            {
                OnTestCompleted(this);
            }

        }
        void _Client_OnClientTestStarted()
        {
            Status = "Test started";
            StartedStatus = 1;
        }

        void _Client_OnDisconnect(StressClientProxy Client)
        {
            if (OnDisconnect != null)
            {
                OnDisconnect(this);
            }
        }

        #endregion




    }
}
